package cn.wuqingna.skillview

import cn.wuqingna.skillview.SkillView.reloadSkillViewPapi
import cn.wuqingna.skillview.SkillView.reloadjobPapi
import com.bh.planners.api.PlannersAPI
import com.bh.planners.api.PlannersAPI.isMax
import com.bh.planners.api.PlannersAPI.plannersProfile
import com.bh.planners.core.pojo.player.PlayerJob
import com.bh.planners.core.ui.Faceplate
import com.bh.planners.core.ui.SkillIcon.Companion.toIcon
import eos.moe.dragoncore.api.gui.event.CustomPacketEvent
import eos.moe.dragoncore.network.PacketSender
import org.bukkit.entity.Player
import taboolib.common.platform.event.SubscribeEvent
import taboolib.common.platform.function.adaptPlayer
import taboolib.library.kether.QuestContext
import taboolib.module.kether.KetherFunction
import taboolib.module.kether.ScriptFrame
import taboolib.module.kether.printKetherErrorMessage

object PacketSendListeners {



    @SubscribeEvent
    fun sendPacketDel(event: CustomPacketEvent){
        when (event.identifier){
            "skill-delete-view" -> PacketSender.sendDeletePlaceholderCache(event.player, "skill-view", true)
            "skill-delete-select" -> PacketSender.sendDeletePlaceholderCache(event.player, "skill-select", true);
            "skill-update-view" -> event.player.reloadSkillViewPapi() //技能信息发包
            "skill-update-job" -> event.player.reloadjobPapi() //职业信息发包
            "skill-tryUpgrade" -> {
                val plannersProfile = event.player.plannersProfile
                val skill = plannersProfile.job?.getSkill(event.data[0]) ?: return;
                PlannersAPI.tryUpgrade(event.player, skill)
            }
        }
    }

    @SubscribeEvent
    fun sendPacketBind(event: CustomPacketEvent){
        if (!event.identifier.equals("skill-view-bind")){return}
        val plannersProfile = event.player.plannersProfile
        val skill = plannersProfile.job?.getSkill(event.data[0]) ?: return;
        val ikey = PlannersAPI.keySlots.first { it.name == event.data[1] }
        ProfileUtil.bind(plannersProfile,skill, ikey)
    }
    @SubscribeEvent
    fun sendPacket(event: CustomPacketEvent){
        if (!event.identifier.equals("skill-view-select")){
            return
        }
        val plannersProfile = event.player.plannersProfile
        val skill = plannersProfile.job?.getSkill(event.data[0]) ?: return;
        var type: String
        if (skill.isMax){
            type = "max"
        } else if ( PlannersAPI.checkUpgrade(event.player, skill)){
            type = "upgrade"
        } else {
            type = "cannot"
        }

        sendSkillInfo(event.player, skill, type);
    }


    fun sendSkillInfo(player: Player, skill: PlayerJob.Skill, upgradeType: String){
        var sb = StringBuffer()
        getDescription(player, skill).forEach {
            sb.append(it).append("\n")
        }
        val map = mutableMapOf<String, String>()
        map["skill-select-texts"] = sb.toString()
        map["skill-select-title"] = skill.name
        sb = StringBuffer()
        toConditionText(player, skill).forEach {
            sb.append(it).append("\n")
        }
        map["skill-select-condition-text"] = sb.toString()
        map["skill-select-upgrade"] = SkillView.config.getString("settings.button.$upgradeType")!!
        PacketSender.sendSyncPlaceholder(player, map)
    }

    fun getDescription(player: Player, skill: PlayerJob.Skill): List<String> {
        val icon = skill.toIcon(player)
        return skill.instance.option.root.getStringList("icon.lore").map { icon.format(it) }
    }

    fun toConditionText(player: Player, skill: PlayerJob.Skill, ): List<String> {
        val list = PlannersAPI.dissatisfyUpgrade(player, skill)
        return if (list.isNotEmpty() && Faceplate.nextCondition.isNotEmpty()) {
            Faceplate.nextCondition.flatMap { s ->
                if (s.contains("\$entry")) {
                    list.filter { it.placeholder != null }.map { s.replace("\$entry", toPlaceholder(player, skill, it.placeholder!!)) }
                } else {
                    listOf(s)
                }
            }
        } else emptyList()
    }

    fun toPlaceholder(player: Player, skill: PlayerJob.Skill, string: String): String {
        return try {
            KetherFunction.parse(string, sender = adaptPlayer(player), namespace = listOf("kether")) {
                rootFrame().rootVariables()["@Skill"] = skill
                rootFrame().rootVariables()["level"] = skill.level
            }
        } catch (e: Throwable) {
            e.printKetherErrorMessage()
            "&cError $string"
        }
    }
    fun ScriptFrame.rootVariables(): QuestContext.VarTable {
        var vars = variables()
        var parent = parent()
        while (parent.isPresent) {
            vars = parent.get().variables()
            parent = parent.get().parent()
        }
        return vars
    }
}